package com.grsu.phonestation.web;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.grsu.phonestation.domain.Admin;
import com.grsu.phonestation.domain.Client;
import com.grsu.phonestation.domain.User;
import com.grsu.phonestation.service.ClientService;
import com.grsu.phonestation.service.UserService;
import com.grsu.phonestation.web.info.RegistrationValidator;

@Controller
public class UserController {

	@Autowired
	@Qualifier("userServiceImpl")
	private UserService<User> userService;

	@Autowired
	@Qualifier("clientServiceImpl")
	private ClientService clientService;

	@RequestMapping(value = { "/", " ", "home" }, method = { RequestMethod.GET })
	public ModelAndView home(HttpSession session, Model model) {

		ModelAndView mav = new ModelAndView();

		Object userObject = session.getAttribute("user");

		if ((userObject != null) && (userObject instanceof User)) {

			if (userObject instanceof Client) {
				User user = (Client) userObject;
				mav.addObject("user", user);
				mav.setViewName("home");
			} else {
				User user = (Admin) userObject;
				mav.addObject("user", user);
				mav.setViewName("admin.home");
			}
		} else {
			mav.setViewName("login");
		}

		return mav;
	}

	@RequestMapping(value = { "/login" }, method = { RequestMethod.GET })
	public String login() {
		return "login";
	}

	@RequestMapping(value = "/login", method = { RequestMethod.POST })
	public ModelAndView login(
			@RequestParam(value = "username", required = true) String username,
			@RequestParam(value = "password", required = true) String password,
			HttpServletRequest request, HttpSession session) {

		ModelAndView mav = new ModelAndView();

		User user = userService.loadUserByCredentials(username, password);

		if (user != null) {
			session.setAttribute("user", user);
			mav = new ModelAndView("redirect:/home");
		} else {
			mav.addObject("error", "Invalid username or password!");
			mav.setViewName("login");
		}

		return mav;
	}

	@RequestMapping(value = "/logout")
	public ModelAndView logout(HttpSession session) {

		ModelAndView model = new ModelAndView();
		model.setViewName("login");

		session.setAttribute("user", null);
		session.invalidate();

		return model;
	}

	@RequestMapping(value = "home/edit", method = { RequestMethod.POST })
	public ModelAndView editUser(@Valid @ModelAttribute User user,

	HttpSession session, Model model) {

		ModelAndView mav = new ModelAndView("redirect:/home");

		Object userObject = session.getAttribute("user");

		if ((userObject != null) && (userObject instanceof User)) {

			User currentUser = (User) userObject;
			currentUser.setFirstname(user.getFirstname());
			currentUser.setLastname(user.getLastname());
			currentUser.setPhone(user.getPhone());
			currentUser.setEmail(user.getEmail());

			userService.editUser(currentUser);

			mav.addObject("user", currentUser);
		} else {
			mav.setViewName("login");
		}

		return mav;
	}

	@RequestMapping(value = { "/users" }, method = { RequestMethod.GET })
	public ModelAndView listClients(HttpSession session, Model model) {

		ModelAndView mav = new ModelAndView();

		Object userObject = session.getAttribute("user");
		if (userObject != null && userObject instanceof Admin) {
			Admin user = (Admin) userObject;

			List<Client> clients = clientService.listUsers();

			mav.addObject("user", user);
			mav.addObject("clients", clients);
			mav.setViewName("admin.users");
		} else {
			mav = new ModelAndView("redirect:/login");
			mav.setViewName("login");
		}

		return mav;
	}

	@RequestMapping(value = "/users/delete/{id}", method = RequestMethod.GET)
	public ModelAndView deliteClient(@PathVariable("id") Integer clientId,
			HttpSession session, Model model) {

		ModelAndView mav = new ModelAndView("redirect:/users");

		clientService.removeUser(clientId);

		return mav;
	}

	@RequestMapping(value = "/users/edit", method = RequestMethod.POST)
	public ModelAndView changeClient(@Valid @ModelAttribute Client user,
			Integer idClient,

			HttpSession session, Model model) {

		ModelAndView mav = new ModelAndView("redirect:/users");

		Client client = clientService.getUserById(idClient);

		if (client != null) {

			client.setFirstname(user.getFirstname());
			client.setLastname(user.getLastname());
			client.setPhone(user.getPhone());
			client.setEmail(user.getEmail());
			client.setActive(user.getActive());

			userService.editUser(client);

			mav.addObject("user", client);
		} else {
			mav.setViewName("login");
		}

		return mav;
	}
	
	@RequestMapping(value = { "/registration" }, method = RequestMethod.POST)
	public ModelAndView registration(
			@ModelAttribute("client") @Valid Client client,
			String repeatPassword, BindingResult result) {

		ModelAndView mav = new ModelAndView();

		RegistrationValidator validator = new RegistrationValidator();

		boolean loginBusy;
		boolean emailBusy;

		if (userService.getUserByLogin(client.getLogin()) != null) {
			loginBusy = true;
		} else {
			loginBusy = false;
		}
		
		if (userService.getUserByEmail(client.getEmail()) != null) {
			emailBusy = true;
		} else {
			emailBusy = false;
		}

		validator.loginBusy(loginBusy);
		validator.emailBusy(emailBusy);
		validator.setRepeatPassword(repeatPassword);
		validator.validate(client, result);

		if (result.hasErrors()) {
			mav = new ModelAndView("registration");
			mav.addObject("result", result);
			
			return mav; 
		}

		clientService.addUser(client);

		mav = new ModelAndView("redirect:/login");

		return mav;
	}

	@RequestMapping(value = { "/registration" }, method = { RequestMethod.GET })
	public ModelAndView registration(Model model) {

		ModelAndView mav = new ModelAndView();
		mav.addObject("registration", new User());
		mav.setViewName("registration");

		return mav;
	}

}
